package com.spring.demo12.eg4;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

/**
 * spring事务使用的简化方式
 * 1.面相接口的方式来简化事件广播器实现：实现ApplicationEventPublisherAware接口来广播事件
 *
 * <br>
 * spring容器在创建bean的过程中，会判断bean是否为 ApplicationListener 类型，进而会将其作为监
 * 听器注册到 AbstractApplicationContext#applicationEventMulticaster 中，这块的源码在
 * org.springframework.context.support.ApplicationListenerDetector#postProcessAfterInitialization
 *
 * @author vhans
 */
@Component
public class UserRegisterService implements ApplicationEventPublisherAware {
    // 接口ApplicationEventPublisher，用来发布事件的，内部定义2个方法都是用来发布事件的
    // 这个接口的实现类中，比如 AnnotationConfigApplicationContext 内部将这2个方法委托给
    // ApplicationEventMulticaster#multicastEvent 进行处理了
    private ApplicationEventPublisher applicationEventPublisher;

    public void registerUser(String name) {
        System.out.printf("用户[%s]注册成功\n", name);
        // 调用AbstractApplicationContext（AbstractApplicationContext继承ApplicationEventPublisher）中的publishEvent方法，也实现广播事件的效果
        this.applicationEventPublisher.publishEvent(new UserRegisterEvent(this, name));
    }

    // spring容器会通过setter将ApplicationEventPublisher（已经装配好所有Listener）注入进来，然后我们就可以使用这个来发布事件了
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }
}
